#! /usr/bin/python3
# -*- coding: utf-8 -*-

import simplejson as json
import pickle

class TreeNode:
    def __init__(self, letter, data):
        letters = u"абвгдеёжзийклмнопрстуфхцчшщьыэюя"
        self.sign = letter
        self.data = data
        self.parent = None
        self.level = 0
        self.leafs = {}
        #for letter in letters:
        #    self.leafs[letter] = None

    def set_leaf(self, letter, node):
        if self.leafs.has_key(letter):
            raise Exception("Try to redefine exist leaf")

        node.level = self.level + 1
        node.parent = self
        self.leafs[letter] = node
        return node

    def get_leaf(self, letter):
        if self.leafs.has_key(letter):
            return self.leafs[letter]
        else:
            new_node = TreeNode(letter, None)
            return self.set_leaf(letter, new_node)

    def get_key(self):
        key = ""
        node = self
        while node.parent != None:
            key += node.sign
            node = node.parent

        return key[::-1]

    def leaf_exists(self, letter):
        return self.leafs.has_key(letter)

    def get_parent(self):
        if self.parent != None:
            return parent
        else:
            raise Exception("Node '%s' have not parent" % self.sign)

    def childs_count(self):
        return len(self.leafs)

    def to_json(self):
        if self.data:
            data = {'key': self.get_key(), 'data': self.data}
            return json.dumps(data)
        else:
            return None

    def readline(self):
        pass

    def read(self, arg):
        print "Read: %s" % arg

    def __setstate__(self, dict):
        #print "SetState: %s\n" % dict
        self.__dict__.update(dict)

    def __getstate__(self):
        #print "GetState"
        return self.__dict__.copy()

class TreeBook:
    def __init__(self):
        self.root = TreeNode('', None)

    def find(self, word):
        previous_node = node = self.root
        length = len(word)
        i = 0
        while True:
            char = word[i]

            # get leaf
            #previous_node = node
            node = node.get_leaf(char)

            i += 1

            # key reached
            if i >= length:
                return node


    def set(self, world, data):
        length = len(world)
        node = self.find(world)

        if node.data != None:
            print "Data for '%s' already exist" % (world)
        else:
            node.data = data

        return node

    def list_node(self, node, callback):
        if node.data:
            callback(node)

        for value in node.leafs.values():
            self.list_node(value, callback)

    def list(self):
        def callback(node):
            print "'%s' = %s" % (node.get_key(), node.data)

        self.list_node(self.root, callback)

    def save_to_file(self, filename):
        f = open(filename, "w")
        pickle.dump(self.root, f)
        f.close()

    def load_from_file(self, filename):
        try:
            f = open(filename, "r")
            self.root = pickle.load(f)
            f.close()
        except IOError as (errno, strerror):
            if errno == 2:
                pass
            else:
                raise IOError(errno, strerror)